﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.IO;
using System.Windows.Forms;
using System.Xml.XPath;
using System.Xml.Linq;
using System.Xml;
using System.Drawing;

namespace CustomerEmailer.Common
{
    public static class Utils
    {
    
        public const string MatchEmailPattern = @"^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$";
        public static bool shouldUpate = false;
        public static long historyRevision=-1;
        public static long contactsRevision=-1;
        public static bool updatingContacts=false;
        public static bool updatingHistory = false;
        public static bool synchronzingContacts = false;

        /// <summary>
        /// Checks whether the given Email-Parameter is a valid E-Mail address.
        /// </summary>
        /// <param name="email">Parameter-string that contains an E-Mail address.</param>
        /// <returns>True, when Parameter-string is not null and 
        /// contains a valid E-Mail address;
        /// otherwise false.</returns>
        public static bool IsEmail(string email)
        {
            if (email != null) return Regex.IsMatch(email, MatchEmailPattern);
            else return false;
        }

        public static string GetSetting(string settingKey)
        {
            string fileLocation = Utils.GetXmlFileLocation("settings.xml");
            XDocument xDoc = XDocument.Load(fileLocation);
            var config = xDoc.Element("configuration").Element(settingKey);
            if (config == null)
            {
                return string.Empty;
            }
            return config.Value.Trim();
        }

        public static string GetXmlFileLocation(string fileName)
        {
            
            string path = string.Format(@"{0}\{1}",
                          Directory.GetParent(Application.ExecutablePath).ToString(),
                          string.Format(@"ApplicationData\{0}", fileName));

            return path;
        }

        public static string GetMainFolderLocation(string fileName)
        {

            string path = string.Format(@"{0}\{1}",
                          Directory.GetParent(Application.ExecutablePath).ToString(), fileName);

            return path;
        }

        public static string GetXMLString(string XMLPath)
        {
            XmlDocument dom = new XmlDocument();
            dom.Load(Utils.GetXmlFileLocation(XMLPath));
            StringWriter stringWriter = new StringWriter();
            XmlTextWriter xmlTextWriter = new XmlTextWriter(stringWriter);
            dom.WriteTo(xmlTextWriter);
            return stringWriter.ToString();
        }

      /*  public static string getXMLHash(string XMLPath)
        {
            //string XMLString = GetXMLString(XMLPath);
          //  return ComputeHash("MD5", GetBytesFromFile("C:\\SyncServer\\customers.xml"));
            //return Hash(XMLString);
        }*/

   /*     public static string Hash(String s)
        {
            HashAlgorithm Hasher = new SHA256CryptoServiceProvider();
            byte[] strBytes = Encoding.UTF8.GetBytes(s);
            byte[] strHash = Hasher.ComputeHash(strBytes);
            return BitConverter.ToString(strHash).Replace("-", "").ToLowerInvariant().Trim();
        }
        */
      /*  public static byte[] GetBytesFromFile(string fullFilePath)
        {
            FileStream fs = File.OpenRead(fullFilePath);
            try
            {
                byte[] bytes = new byte[fs.Length];
                fs.Read(bytes, 0, Convert.ToInt32(fs.Length));
                fs.Close();
                return bytes;
            }
            finally
            {
                fs.Close();
            }

        }*/
        /*
        public static string ComputeHash(
                                    string hashAlgorithm, byte[] plainTextBytes)
        {
          

            // Convert plain text into a byte array.
            //byte[] plainTextBytes = Encoding.UTF8.GetBytes(plainText);

            // Because we support multiple hashing algorithms, we must define
            // hash object as a common (abstract) base class. We will specify the
            // actual hashing algorithm class later during object creation.
            HashAlgorithm hash;

            // Make sure hashing algorithm name is specified.
            if (hashAlgorithm == null)
                hashAlgorithm = "";

            // Initialize appropriate hashing algorithm class.
            switch (hashAlgorithm.ToUpper())
            {
                case "SHA1":
                    hash = new SHA1Managed();
                    break;

                case "SHA256":
                    hash = new SHA256Managed();
                    break;

                case "SHA384":
                    hash = new SHA384Managed();
                    break;

                case "SHA512":
                    hash = new SHA512Managed();
                    break;

                default:
                    hash = new MD5CryptoServiceProvider();
                    break;
            }

            // Compute hash value of our plain text with appended salt.
            byte[] hashBytes = hash.ComputeHash(plainTextBytes);

            // Convert result into a base64-encoded string.
            string hashValue = Convert.ToBase64String(hashBytes);

            // Return the result.
            return hashValue;
        }

        */

        public static void FindNodeInHierarchy(TreeNodeCollection nodes, TreeView t2,string strSearchValue, TreeView treeView1)
        {
            for (int iCount = 0; iCount < nodes.Count; iCount++)
            {
                if (nodes[iCount].Text.ToUpper().Contains(strSearchValue.ToUpper()))
                {
                    //treeView1.SelectedNode = nodes[iCount];
                    //nodes[iCount].Expand();
                    if (nodes[iCount].ImageKey == "Email")
                    {
                        t2.Nodes.Add((TreeNode)nodes[iCount].Parent.Clone());
                    }
                    else
                    {
                        t2.Nodes.Add((TreeNode)nodes[iCount].Clone());
                    }
                }
                FindNodeInHierarchy(nodes[iCount].Nodes, t2,strSearchValue,treeView1);

                /*if (!(nodes[iCount].Text.ToUpper().Contains(strSearchValue.ToUpper())) && nodes[iCount].Nodes.Count == 0)
                    nodes[iCount].Remove();*/
            }
        }
        

        public static bool isNodeThere(TreeNodeCollection nodes,string nodeString)
        {
            foreach (TreeNode node in nodes)
            {
                return isNodeThere(node.Nodes, nodeString) || (node.Text == nodeString);
            }
            return false;
        }

        public static void FindNodeInHierarchyByPath(TreeNodeCollection nodes, string strSearchValue, TreeView treeView1)
        {
            for (int iCount = 0; iCount < nodes.Count; iCount++)
            {
                if (nodes[iCount].ImageKey == "Customers")
                {
                    if (nodes[iCount].Nodes[0].FullPath.ToUpper().Equals(strSearchValue.ToUpper()))
                    {
                        treeView1.SelectedNode = nodes[iCount];
                        nodes[iCount].Expand();
                    }
                }
               FindNodeInHierarchyByPath(nodes[iCount].Nodes, strSearchValue, treeView1);
            }
        }

        public static void SilentlyFindNodeInHierarchyByPath(TreeNodeCollection nodes, string strSearchValue,ref TreeNode res, string type)
        {
            for (int iCount = 0; iCount < nodes.Count; iCount++)
            {
                if (nodes[iCount].ImageKey == type)
                {
                    if (nodes[iCount].FullPath.ToUpper().Equals(strSearchValue.ToUpper()))
                    {
                        res = nodes[iCount];
                    }
                }
                SilentlyFindNodeInHierarchyByPath(nodes[iCount].Nodes, strSearchValue,ref res,type);
            }
        }

        public static void getEquivalentNodes(TreeNodeCollection parents, ref List<TreeNode> nodes_list, TreeNode myNode)
        {
            for (int i = 0; i < parents.Count; i++)
            {
                if (parents[i].ImageKey == "Customers")
                {
                    if (parents[i].Nodes[0].Text.ToUpper().Equals(myNode.Nodes[0].Text.ToUpper()))// if my email == his email
                        nodes_list.Add(parents[i]);
                }
                getEquivalentNodes(parents[i].Nodes, ref nodes_list, myNode);
            }
            return;
        }

        public static TreeNode getFrozenNode(TreeNodeCollection parents)
        {
            foreach (TreeNode node in parents)
                if (node.ImageKey == "FreezeGrp")
                    return node;
            return null;
        }

        public static System.Drawing.Drawing2D.GraphicsPath drawRoundedRect(int x, int y, int radius, int height, int width)
        {
            System.Drawing.Drawing2D.GraphicsPath gp = new System.Drawing.Drawing2D.GraphicsPath();
            //gp.AddLine(x + radius, y, x + width - (radius * 2), y);
            gp.AddLine(x , y, x + width, y);
            //gp.AddArc(x + width - (radius * 2), y, radius * 2, radius * 2, 270, 90);
            gp.AddLine(x + width, y + radius, x + width, y + height - (radius * 2));
            gp.AddArc(x + width - (radius * 2), y + height - (radius * 2), radius * 2, radius * 2, 0, 90);
            gp.AddLine(x + width - (radius * 2), y + height, x + radius, y + height);
            gp.AddArc(x, y + height - (radius * 2), radius * 2, radius * 2, 90, 90);
            gp.AddLine(x, y + height - (radius * 2), x, y + radius);
            //gp.AddArc(x, y, radius * 2, radius * 2, 180, 90);
            gp.CloseFigure();
            return gp;
        }

        public static void drawBorder(int x, int y, int radius, int height, int width,PaintEventArgs e)
        {
            e.Graphics.DrawLine(new Pen(Color.Black,5),x , y, x + width, y);
            e.Graphics.DrawLine(new Pen(Color.Black, 5), x + width, y , x + width, y + height);
            e.Graphics.DrawArc(new Pen(Color.Black, 5), x + width - (radius * 2), y + height - (radius * 2), radius * 2, radius * 2, 0, 90);
            e.Graphics.DrawLine(new Pen(Color.Black, 5), x + width , y + height, x, y + height);
            e.Graphics.DrawArc(new Pen(Color.Black, 5), x, y + height - (radius * 2), radius * 2, radius * 2, 90, 90);
            e.Graphics.DrawLine(new Pen(Color.Black, 5), x, y + height, x, y);
        }

        public static void copyTreeView(TreeView copyTree, ref TreeView toTree)
        {
            toTree.Nodes.Clear();
            foreach (TreeNode node in copyTree.Nodes)
            {
                TreeNode node1= (TreeNode)node.Clone();
                toTree.Nodes.Add(node1);
            }
        }
    }
}
